class Linear {
    constructor(linear) {
        this.canvasSupport(linear);
        this.linear = linear;
        this.canvasW = linear.width;
        this.canvasH = linear.height;
        this.ctx = linear.getContext('2d');
        
        return this;
    }

    /**
     * @desc 初始化检测
     */
    canvasSupport = () => {
        if(!this.linear || !this.linear.getContext) {
            return new Error('初始化失败')
        }
    }

    /**
     * @desc 画一条简单的直线
     */
    drawSimplePath = () => {
        this.clear();
        this.ctx.beginPath();
        this.ctx.lineWidth = 1;
        this.ctx.strokeStyle = '#000';
        this.ctx.moveTo(10, 10);
        this.ctx.lineTo(100, 100);
        this.ctx.stroke();
        this.ctx.closePath();
    }

    /**
     * @desc 画一条更宽的红色直线
     */
    drawWeightPath = () => {
        this.clear();
        this.ctx.beginPath();
        this.ctx.lineWidth = 10;
        this.ctx.strokeStyle = '#c00';
        this.ctx.moveTo(100, 10);
        this.ctx.lineTo(10, 100);
        this.ctx.stroke();
        this.ctx.closePath();
    }

    /**
     * @desc 画一条更宽的渐变直线
     */
    drawGradientPath = () => {
        this.clear();
        this.ctx.beginPath();
        this.ctx.lineWidth = 10;

        var canvasGradient = this.ctx.createLinearGradient(50, 50, 250, 50);
        canvasGradient.addColorStop(0, "white");
        canvasGradient.addColorStop(1, "#c00");

        this.ctx.strokeStyle = canvasGradient;
        this.ctx.moveTo(10, 50);
        this.ctx.lineTo(100, 50);
        this.ctx.stroke();
        this.ctx.closePath();
    }

    /**
     * @desc 多路径不间断
     */
    drawPolyLinePath = () => {
        this.clear();
        this.ctx.strokeStyle = '#c00';
        this.ctx.lineWidth = 4;

        this.ctx.beginPath();
        this.ctx.moveTo(50, 10);
        this.ctx.lineTo(150, 10);
        this.ctx.lineTo(150, 200);
        this.ctx.lineTo(200, 200);
        this.ctx.lineTo(200, 150);
        this.ctx.stroke();
        this.ctx.closePath();
    }

    /**
     * @desc 多路径间断，填充最后一个
     */
    drawBrokePolyLinePath = () => {
        this.clear();
        this.ctx.strokeStyle = '#c00';
        this.ctx.lineWidth = 4;

        this.ctx.beginPath();
        this.ctx.moveTo(50, 10);
        this.ctx.lineTo(150, 10);
        this.ctx.lineTo(150, 200);
        this.ctx.stroke();
        this.ctx.closePath();

        this.ctx.beginPath();
        this.ctx.moveTo(200, 200);
        this.ctx.lineTo(200, 150);
        this.ctx.lineTo(300, 200);
        this.ctx.stroke();
        this.ctx.closePath();
        this.ctx.fill();
        
    }

    /**
     * @desc 多路径间断,不带beginPath,closePath
     */
    drawBrokePolyLineErrorPath = () => {
        this.clear();
        this.ctx.strokeStyle = '#c00';
        this.ctx.lineWidth = 4;

        this.ctx.beginPath()
        
        this.ctx.moveTo(50, 10);
        this.ctx.lineTo(150, 10);
        this.ctx.lineTo(150, 200);
        this.ctx.stroke();

        
        this.ctx.moveTo(200, 200);
        this.ctx.lineTo(200, 150);
        this.ctx.lineTo(300, 200);
        this.ctx.stroke();
        this.ctx.fill();
        
    }

    /**
     * @desc 比较closePath和stroke先后执行的区别
     */
    drawCompareStepPath = () => {
        this.clear();
        this.ctx.strokeStyle = 'red';
        this.ctx.lineWidth = 4;

        // stroke时，路径已经封闭
        this.ctx.beginPath();
        this.ctx.moveTo(50, 10);
        this.ctx.lineTo(150, 10);
        this.ctx.lineTo(150, 200);
        this.ctx.lineTo(200, 200);
        this.ctx.lineTo(200, 150);
        this.ctx.stroke();
        this.ctx.closePath();

        // closePath会将当前路径端点和路径起始端点连接起来
        this.ctx.strokeStyle = 'blue';
        this.ctx.beginPath();
        this.ctx.moveTo(250, 10);
        this.ctx.lineTo(350, 10);
        this.ctx.lineTo(350, 200);
        this.ctx.lineTo(400, 200);
        this.ctx.lineTo(400, 150);
        this.ctx.closePath();
        this.ctx.stroke();
    }

    /**
     * @desc 填充 closePath和stroke先后执行
     */
    drawCompareStepFill = () => {
        this.clear();
        this.ctx.fillStyle = 'pink';

        // stroke时，路径已经封闭
        this.ctx.beginPath();
        this.ctx.moveTo(50, 10);
        this.ctx.lineTo(150, 10);
        this.ctx.lineTo(150, 200);
        this.ctx.lineTo(200, 200);
        this.ctx.lineTo(200, 150);
        this.ctx.fill();
        this.ctx.closePath();

        // closePath会将当前路径端点和路径起始端点连接起来
        this.ctx.fillStyle = 'green';
        this.ctx.beginPath();
        this.ctx.moveTo(250, 10);
        this.ctx.lineTo(350, 10);
        this.ctx.lineTo(350, 200);
        this.ctx.lineTo(400, 200);
        this.ctx.lineTo(400, 150);
        this.ctx.closePath();
        this.ctx.fill();
    }

    /**
     * @desc 像素边界，一像素线性路径
     */
    drawDiffLinePath = () => {
        this.clear();

        this.ctx.strokeStyle = 'red'; 
        this.ctx.lineWidth = 1; 
        this.ctx.beginPath(); 
        this.ctx.moveTo(50, 50); 
        this.ctx.lineTo(350, 50); 
        this.ctx.stroke(); 
        
        this.ctx.beginPath(); 
        this.ctx.moveTo(50.5, 100.5); 
        this.ctx.lineTo(350.5,100.5); 
        this.ctx.stroke();
    }

    /**
     * @desc 绘制虚线
     */
    drawDashedPath = segments => {
        this.clear();
        this.ctx.strokeStyle = '#f36'||this.getRandomColor();
        this.ctx.setLineDash(segments);
        this.ctx.lineWidth = 4;

        this.ctx.beginPath();
        this.ctx.moveTo(10, 100);
        this.ctx.lineTo(200, 100);
        this.ctx.stroke();
        this.ctx.closePath()
    }

    /**
     * @desc 奇数，偶数比较
     */
    drawDashCompare = () => {
        this.clear();
        this.ctx.strokeStyle = '#f36';
        this.ctx.setLineDash([40, 30, 20]);
        this.ctx.lineWidth = 4;

        this.ctx.beginPath();
        this.ctx.moveTo(10, 100);
        this.ctx.lineTo(400, 100);
        this.ctx.stroke();
        this.ctx.closePath();

        this.ctx.setLineDash([40, 30, 20, 10]);
        this.ctx.strokeStyle = 'blue';
        this.ctx.beginPath();
        this.ctx.moveTo(10, 120);
        this.ctx.lineTo(400, 120);
        this.ctx.stroke();
        this.ctx.closePath();
    }

    /**
     * @desc 虚线矩形
     */
    drawDashRect = () => {
        this.clear();
        this.ctx.strokeStyle = '#f36';
        this.ctx.setLineDash([10]);
        this.ctx.lineWidth = 4;
        this.ctx.beginPath();
        this.ctx.strokeRect(20, 10, 160, 100);
        this.ctx.closePath();
    }

    /**
     * @desc 画个圆试试
     */
    drawCircle = () => {
        this.clear();
        this.ctx.fillStyle = '#fecc50';
        this.ctx.beginPath();
        this.ctx.arc(100, 200, 50, 0, 2 * Math.PI);
        this.ctx.arc(300, 200, 50, 0, 2 * Math.PI);
        this.ctx.fill();
        this.ctx.closePath()
    }

    /**
     * @desc 绘制圆点线，只做演示，不做完备
     * @param x1 起始点x坐标
     * @param y1 起始点y坐标
     * @param x2 终点x坐标
     * @param y2 终点y坐标
     * @param interval 间隔距离
     */
    drawDottedPath = (x1, y1, x2, y2, interval) => {
        if(!interval){
            interval = 5;
        }

        // 水平
        var isHorizontal = true;

        if(x1 === x2) {
            isHorizontal = false;
        }

        var len = isHorizontal ? x2 - x1 : y2 - y1;

        this.ctx.moveTo(x1, y1);

        var progress = 0;

        while(len > progress) {
            progress += interval;

            if(progress > len){
                progress = len;
            }
            this.ctx.fillStyle = '#f36';
            if(isHorizontal){
                this.ctx.moveTo(x1 + progress, y1);
                this.ctx.arc(x1 + progress, y1, 1, 0, 2 * Math.PI);
                this.ctx.fill()
            }else {
                this.ctx.moveTo(x1, y1 + progress);
                this.ctx.arc(x1, y1 + progress, 1, 0, 2 * Math.PI);
                this.ctx.fill();
            }
        }
    }

    /**
     * @desc 画线帽
     * @param lineCap butt, round, square
     */
    drawLineCap = (lineCap) => {
        this.clear();
        this.ctx.beginPath();
        this.ctx.lineWidth = 30;
        this.ctx.strokeStyle = '#f36';
        this.ctx.lineCap = lineCap;
        this.ctx.moveTo(50, 100);
        this.ctx.lineTo(400, 100);
        this.ctx.stroke();
        this.ctx.closePath();
    }


    /**
     * @desc 方法清空给定矩形内的指定像素
     */
    clear = () => {
        this.ctx.clearRect(0, 0, this.canvasW, this.canvasH);
    }

    /**
     * @desc 获取随机色
     */
    getRandomColor = () => {
        return '#' + Math.floor( Math.random() * 0xffffff ).toString(16);
    }
    

}

export default Linear;